package def;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import setting.BioNLPSettings;
import abs.PlainText;

public class AbstractText extends PlainText {

	public AbstractText(String filename, BioNLPDocument doc){
		super(filename);
		ArrayList<String> list = new ArrayList<String>();
		ArrayList<Integer> startPos = new ArrayList<Integer>(), endPos = new ArrayList<Integer>();
		int start = 0;

		Matcher m = BioNLPSettings.sentSplitter.matcher(text);
		while (m.find()){
			// FIXME include protein span info
			if (text.substring(m.start()-3, m.start()).matches(",\\s[A-Z]")
					|| text.substring(m.start()-3, m.start()).equals("e.g")
					|| text.substring(m.start()-3, m.start()).equals("i.e")
					|| text.substring(m.start()-2, m.start()).equals("vs")
					|| text.substring(m.start()-2, m.start()).equals("Dr") 
					|| text.substring(m.start()-5, m.start()).equals("et al")
					|| (text.substring(m.start()-2, m.start()).matches(" [D-Z]") && 
							(!withinProteinBoundary(m.start()-1, doc)&&!text.substring(m.start()-7, m.start()-2).equals("kappa")))
							|| text.substring(start, m.end(1)).trim().length() <= 3)
				continue;
			String sent = text.substring(start, m.end(1)).trim();

			if (sent.length() > 500){
				int clStart = 0;
				System.err.println("[AbstractText] long sentence : "+doc.fileId);
				// special treatment
				Matcher cm = BioNLPSettings.clauseSplitter.matcher(sent);
				while (cm.find()){
					String cl = sent.substring(clStart, cm.end(1));
					list.add(cl);
					startPos.add(start + clStart);
					endPos.add(start + clStart + cl.length());
					clStart += cl.length();
					if (clStart != cm.end(1) )
						System.err.print("constructor@AbstractText CLAUSE split into more than 2 sents and position calc is wrong "+filename +" with ["+cl+"]");
				}
				// add the last clause
				String cl = sent.substring(clStart);
				list.add(cl);
				startPos.add(start + clStart);
				endPos.add(start + clStart + cl.length());
			}else{
				if (sent.contains("\n")){
					String[] sents = sent.split("\n");
					if (sents.length>2){
						System.err.println("constructor@AbstractText sent split into more than 2 sents "+filename);
					}
					int start1 = start;
					for (int i = 0; i < sents.length; i++){
						list.add(sents[i]);
						startPos.add(start1);
						endPos.add(start1+sents[i].length());
						start1 += sents[i].length()+1;// +1 because of the line break;
					}
					if (start1!=m.end(1)){
						System.err.println("constructor@AbstractText sent split into more than 2 sents and position calc is wrong"+filename);
					}
				}
				else{
					list.add(sent);
					startPos.add(start);
					endPos.add( start + sent.length());
				}
			}
			start = m.end(1);
		}
		if (start != text.length() && text.substring(start).trim().length() != 0){
			String sent = text.substring(start).trim();
			list.add(sent);
			startPos.add(start);
			endPos.add(start+ sent.length());
		}
		//		Span[] sentences = BioNLPSettings.sentenceDetector.sentPosDetect(text);
		//		lines = new String[sentences.length];
		lines = list.toArray(new String[0]);
		sentStartPos = new int[lines.length];
		sentEndPos = new int[lines.length];
		for (int i =0; i < lines.length; i++){
			//			lines[i] = (sentences[i].getCoveredText(text).toString());
			sentStartPos[i] = startPos.get(i);
			sentEndPos[i] = endPos.get(i);
		}
	}
	private boolean withinProteinBoundary(int start, BioNLPDocument doc) {
		for (Protein p :doc.proteins){
			if (p.tspan.startIdx <= start && start< p.tspan.endIdx){
				return true;
			}
		}
		return false;
	}
	private boolean proteinBoundary(int i, BioNLPDocument doc) {
		for (Protein p :doc.proteins){
			if (p.tspan.endIdx == i){
				return true;
			}
		}
		return false;
	}
	/**
	 * given a pos, return the sentence containing it.
	 * @return
	 */
	public int getSentenceIdByPos(int start){
		for (int i = 0; i < lines.length; i++){
			if (sentStartPos[i] <= start && sentEndPos[i] > start){
				return i;
			}
		}
		return -1;
	}

	public final String[] lines ;
	public final int[] sentStartPos,  sentEndPos;  
}
